package rainy.file.synchronization.client.file;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.HashSet;
import java.util.Set;

import rainy.file.synchronization.client.FileSendClient;

/**
 * 
 * 
 * @author Grom
 *
 */
public class FolderMonitor extends Thread {
	private String folderPath;
	private static Set<FolderMonitor> monitorPool = new HashSet<>();
	private WatchService watchService;

	public FolderMonitor(String folderPath) {
		super(folderPath);
		this.folderPath = folderPath;
		new File(folderPath).listFiles(new FileFilter() {
			public boolean accept(File pathname) {
				if (pathname.isDirectory()) {
					new FolderMonitor(pathname.getAbsolutePath()).start();
					System.out.println("[Folder monitor ]  + [" + pathname + "] started!");
				}
				return false;
			}
		});
	}

	public void run() {
		Path path = Paths.get(folderPath);
		try {
			watchService = path.getFileSystem().newWatchService();
			path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
			monitorPool.add(this);

			while (true) {
				WatchKey key = watchService.take();
				for (WatchEvent<?> event : key.pollEvents()) {
					System.out.println("[Folder monitor ] " + event.context() + "  " + event.kind() + " was triggered");
					Object obj = event.context();
					if (obj instanceof Path) {
						File file = ((Path) obj).toFile();
						File realFile = new File(folderPath, file.getPath());
						if (realFile.getParentFile() == null || !realFile.getParentFile().exists()) {
							monitorPool.remove(this);
							this.watchService.close();
							break;
						}
						if (realFile.isDirectory()) {
							/**
							 * for new added folder, start to monitor the folder
							 * and arrange to send all the files under it
							 */
							new FolderMonitor(realFile.getAbsolutePath()).start();
							System.out.println("[Folder monitor ]  [new ADDED] + [" + realFile + "] started!");
							continue;
						} else {
							System.out.println("[Folder monitor ]  [TOSEND] + [" + realFile + "] started!");
							FileSendClient.addNewAddedFile(realFile);
						}
					}
				}
				if (!key.reset()) {
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
